home *** CD-ROM | disk | FTP | other *** search
- /* LIB.C
- *
- * Basic Library Resource Handling
- *
- * This code is based on the example shared library,
- * found on the DICE 3.0 disks.
- *
- * This code doesn't use any form of startup code (the example does).
- * This is not something the novice C-programmer should attemt.
- * You need to know what you are doing. :)
- */
-
- #include "async.h"
- #include <exec/libraries.h>
- #include <exec/resident.h>
- #include "rev.h"
-
- #include <clib/asyncio_protos.h>
-
-
- LibCall struct Library *LibInit( _REG( d0 ) struct Library *, _REG( a0 ) APTR, _REG( a6 ) struct ExecBase * );
- struct Library *LibOpen( _REG( a6 ) struct Library * );
- APTR LibClose( _REG( a6 ) struct Library * );
- APTR LibExpunge( _REG( a6 ) struct Library * );
-
- /* Due to a bug in the linker, we must have some initialized data.
- * If not, the linker will not produce any smalldata section.
- * By giving one of the fields a value, this problems is solved.
- *
- * The other variables will be cleared, since "The memory used for
- * bss blocks is zeroed by the loader when it is allocated" (quote
- * from the AmigaDOS manual).
- */
- struct Library *LibBase = NULL; /* Our library structure */
- struct ExecBase *SysBase;
- struct Library *UtilityBase;
- struct DosLibrary *DOSBase;
- APTR SegList;
-
-
- /* In case the user tries to run us, simply exit immediately.
- * This code is also used for the reserved library function,
- * that all libraries currently must have.
- *
- * Note that this function *must* be placed before any const
- * data, or else the "exit if run" effect is lost.
- *
- * We also use this code for the "reserved" standard library entry.
- */
- LONG
- LibReserved( VOID )
- {
- return( 0 );
- }
-
-
- /* The functions the library should have. Unfortunately, we can't
- * use the more "compact" format, using 16-bit relative entries,
- * due to the compiler (bug or limitation ;).
- */
- const APTR FuncTable[] =
- {
- LibOpen, /* Standard library functions */
- LibClose,
- LibExpunge,
- LibReserved,
-
- OpenAsync, /* Our functions start here */
- OpenAsyncFromFH,
- CloseAsync,
- SeekAsync,
- ReadAsync,
- WriteAsync,
- ReadCharAsync,
- WriteCharAsync,
-
- ( APTR ) -1 /* Terminate the table */
- };
-
-
- /* Table describing the library. We need this, since we use the
- * autoinit feature. This means we don't need to call MakeLibrary()
- * etc. in LibInit.
- */
- const ULONG InitTable[] =
- {
- sizeof( struct Library ), /* Size of our library base, excluding jump table */
- ( ULONG ) FuncTable, /* The functions we have */
- NULL, /* InitStruct data. We init stuff ourselves instead */
- ( ULONG ) LibInit /* The library init function */
- };
-
-
- const TEXT LibName[] = "asyncio.library";
- const TEXT LibId[] = "asyncio.library "VERSION" (" DATE ")\r\n";
-
-
- /* And finaly the resident structure, used by InitResident(),
- * in order to initialize everything
- */
- const struct Resident RomTag =
- {
- RTC_MATCHWORD, /* rt_MatchWord */
- &RomTag, /* rt_MatchTag */
- LibExpunge, /* rt_EndSkip */
- RTF_AUTOINIT, /* rt_Flags */
- VERNUM, /* rt_Version */
- NT_LIBRARY, /* rt_Type */
- 0, /* rt_Pri */
- LibName, /* rt_Name */
- LibId, /* rt_IDString */
- InitTable /* rt_Init */
- };
-
-
- /* This small function is a generic library structure freer. */
- VOID
- FreeLib( struct Library *lib )
- {
- FreeMem( ( UBYTE * ) lib - lib->lib_NegSize, lib->lib_NegSize + lib->lib_PosSize );
- }
-
-
- /* This function is called when the library is loaded, and the library base
- * is allocated. We are in a forbid section here, so don't do anything
- * time-consuming, Wait() or similar.
- *
- * If all ok, return the library base. If anything went wrong, deallocate
- * the library structure, and return NULL.
- */
- LibCall struct Library *
- LibInit( _REG( d0 ) struct Library *lib, _REG( a0 ) APTR seglist, _REG( a6 ) struct ExecBase *sysBase )
- {
- SysBase = sysBase;
-
- if( DOSBase = ( struct DOSLibrary * ) OpenLibrary( "dos.library", 37 ) )
- {
- if( UtilityBase = OpenLibrary( "utility.library", 37 ) )
- {
- lib->lib_Node.ln_Type = NT_LIBRARY;
- lib->lib_Node.ln_Pri = 0;
- lib->lib_Node.ln_Name = LibName;
- lib->lib_Flags = LIBF_CHANGED | LIBF_SUMUSED;
- lib->lib_Version = VERNUM;
- lib->lib_Revision = REVNUM;
- lib->lib_IdString = ( APTR ) LibId;
- SegList = seglist;
- }
- else
- {
- CloseLibrary( ( struct Library * ) DOSBase );
- FreeLib( lib );
- return( NULL );
- }
- }
- else
- {
- FreeLib( lib );
- return( NULL );
- }
-
- return( lib );
- }
-
-
- /* Open is given the library pointer. Either return the library pointer or NULL.
- * Remove the DELAYED-EXPUNGE flag. Exec has Forbid() for us during the call.
- */
- struct Library *
- LibOpen( _REG( a6 ) struct Library *lib )
- {
- ++lib->lib_OpenCnt;
- lib->lib_Flags &= ~LIBF_DELEXP;
- return( lib );
- }
-
-
- /* Close is given the library pointer. Be sure not to decrement the open
- * count if already zero. If the open count is or becomes zero AND there
- * is a LIBF_DELEXP, we expunge the library and return the seglist.
- * Otherwise we return NULL.
- *
- * Note that this routine never sets LIBF_DELEXP on its own.
- *
- * Exec has Forbid() for us during the call.
- */
- APTR
- LibClose( _REG( a6 ) struct Library *lib )
- {
- if( lib->lib_OpenCnt && --lib->lib_OpenCnt )
- {
- return( NULL );
- }
-
- if( lib->lib_Flags & LIBF_DELEXP )
- {
- return( LibExpunge( lib ) );
- }
-
- return( NULL );
- }
-
-
- /* We expunge the library and return the Seglist ONLY if the open count is zero.
- * If the open count is not zero we set the DELAYED-EXPUNGE flag and return NULL.
- *
- * Exec has Forbid() for us during the call. NOTE ALSO that Expunge might be
- * called from the memory allocator and thus we CANNOT DO A Wait() or otherwise
- * take a long time to complete (straight from RKM).
- *
- * Apparently RemLibrary( lib ) calls our expunge routine and would therefore
- * freeze if we called it ourselves. As far as I can tell from RKM,
- * LibExpunge( lib ) must remove the library itself as shown below.
- */
- LibCall APTR
- LibExpunge( _REG( a6 ) struct Library *lib )
- {
- if( lib->lib_OpenCnt )
- {
- lib->lib_Flags |= LIBF_DELEXP;
- return( NULL );
- }
-
- Remove( &lib->lib_Node );
- FreeLib( lib );
- CloseLibrary( ( struct Library * ) DOSBase );
- CloseLibrary( UtilityBase );
-
- return( SegList );
- }
-